home *** CD-ROM | disk | FTP | other *** search
- /*
- *****************************************************************
- * *
- * Section : Antic Display Modes *
- * Original Author : David Firth *
- * : Thomas Richter (thor) *
- * Date Written : 28th May 1995 *
- * : 17th February 1988 *
- * Version : 1.3 *
- * *
- * *
- * Description *
- * ----------- *
- * *
- * Section that handles Antic display modes. Not required *
- * for BASIC version. *
- * *
- *****************************************************************
- */
-
- #include <stdio.h>
- #include <string.h>
-
- #ifndef AMIGA
- #include "config.h"
- #endif
-
- #include "atari.h"
- #include "rt-config.h"
- #include "mem.h"
- #include "cpu.h"
- #include "gtia.h"
- #include "antic.h"
-
- #define FALSE 0
- #define TRUE 1
-
- int xmin;
- int xmax;
-
- int dmactl_xmin_noscroll;
- int dmactl_xmax_noscroll;
- static int dmactl_xmin_scroll;
- static int dmactl_xmax_scroll;
- static int memory_basis; /* refresh cycles needed for memory */
- static int pm_dma; /* DMA cycles needed by P/M graphics */
- static int char_delta;
- static int char_offset;
- static int invert_mask;
- static int blank_mask;
- static int screenaddr;
-
- /* colour lookup tables */
-
- static int lookup_f[256];
- static int lookup_4[256];
- static int lookup24[256];
- static int lookup_6[256];
- static int lookup_9[256];
-
- static char *rcsid = "$Id: antic.c,v 1.30 1998/02/17 thor,david Exp $";
-
- UBYTE CHACTL;
- UBYTE CHBASE;
- UWORD DLIST,DLISTINIT;
- UBYTE DMACTL;
- UBYTE HSCROL;
- UBYTE NMIEN;
- UBYTE NMIST;
- UBYTE PMBASE;
- UBYTE VSCROL;
-
- int DMAwidth;
-
- extern UWORD regPC;
-
- /*
- * These are defined for Word (2 Byte) memory accesses. I have not
- * defined Longword (4 Byte) values since the Sparc architecture
- * requires that Longword are on a longword boundry.
- *
- * Words accesses don't appear to be a problem because the first
- * pixel plotted on a line will always be at an even offset, and
- * hence on a word boundry.
- *
- * Note: HSCROL is in colour clocks whereas the pixels are emulated
- * down to a half colour clock - the first pixel plotted is
- * moved across by 2*HSCROL
- */
-
- #define PF2_COLPF0 0x0404
- #define PF2_COLPF1 0x0505
- #define PF2_COLPF2 0x0606
- #define PF2_COLPF3 0x0707
- #define PF2_COLBK 0x0808
- #define PF2_COLPF1_FID 0x1515
-
- #define PF4_COLPF0 0x04040404
- #define PF4_COLPF1 0x05050505
- #define PF4_COLPF2 0x06060606
- #define PF4_COLPF3 0x07070707
- #define PF4_COLBK 0x08080808
- #define PF4_COLPF1_FID 0x15151515
-
- /* The middle of the display. All color/display/whatever changes BEFORE that
- cycle are seen on the same row.
- All changes after this color clock are visible ON THE NEXT row */
- #define CC_MIDDLE 50
- /* The propagation delay needed by the 6502 to react on the NMI interrupt */
- #define DLI_DELAY 8
- /* The number of cycles available on the same row to proceed after WSYNC and
- before the horizontal blank */
- #define AFTER_WSYNC 20
- /* The number of cycles available after the horizontal blank but before the
- DMA of antic actually starts */
- #define BEFORE_DMA 0
- /* The line where the VSYNC is generated. */
- #define VSYNC_POS 250
-
- int cc_middle=CC_MIDDLE;
- int dli_delay=DLI_DELAY;
- int after_wsync=AFTER_WSYNC;
- int before_dma=BEFORE_DMA;
- int vsync_pos=VSYNC_POS;
-
-
- int ypos;
-
- /*
- * Pre-computed values for improved performance
- */
-
- static int chbase_40; /* CHBASE for 40 character mode */
- static int chbase_20; /* CHBASE for 20 character mode */
- static int maddr_s; /* Address of Missiles - Single Line Resolution */
- static int p0addr_s; /* Address of Player0 - Single Line Resolution */
- static int p1addr_s; /* Address of Player1 - Single Line Resolution */
- static int p2addr_s; /* Address of Player2 - Single Line Resolution */
- static int p3addr_s; /* Address of Player3 - Single Line Resolution */
- static int maddr_d; /* Address of Missiles - Double Line Resolution */
- static int p0addr_d; /* Address of Player0 - Double Line Resolution */
- static int p1addr_d; /* Address of Player1 - Double Line Resolution */
- static int p2addr_d; /* Address of Player2 - Double Line Resolution */
- static int p3addr_d; /* Address of Player3 - Double Line Resolution */
-
- int wsync_halt = 0;
- static int carry=0; /* carry over of CPU cycles */
-
- /*
- =============================================================
- Define screen as ULONG to ensure that it is Longword aligned.
- This allows special optimisations under certain conditions.
- -------------------------------------------------------------
- The extra 16 scanlines is used as an overflow buffer and has
- enough room for any extra mode line. It is needed on the
- occasions that a valid JVB instruction is not found in the
- display list - An automatic break out will occur when ypos
- is greater than the ATARI_HEIGHT, if its one less than this
- there must be enough space for another mode line.
- =============================================================
- */
-
- ULONG *atari_screen = NULL;
- UBYTE *scrn_ptr;
-
- /* I/O register read */
-
- mtype ANTIC_CHBASE_GET(void)
- {
- return CHBASE;
- }
-
- mtype ANTIC_CHACTL_GET(void)
- {
- return CHACTL;
- }
-
- mtype ANTIC_DLISTL_GET(void)
- {
- return DLIST & 0xff;
- }
-
- mtype ANTIC_DLISTH_GET(void)
- {
- return DLIST >> 8;
- }
-
- mtype ANTIC_DMACTL_GET(void)
- {
- return DMACTL;
- }
-
- mtype ANTIC_VCOUNT_GET(void)
- {
- return ypos >> 1;
- }
-
- mtype ANTIC_NMIEN_GET(void)
- {
- return NMIEN | 0x1f;
- }
-
- mtype ANTIC_NMIST_GET(void)
- {
- return NMIST;
- }
-
- mtype ANTIC_WSYNC_GET(void)
- {
- if (wsync_halt)
- printf("Double wsync!\n");
- wsync_halt++;
- return 0xff;
- }
-
- /* I/O put routines */
-
- int ANTIC_CHBASE_PUT(mtype byte)
- {
- CHBASE = byte;
- chbase_40 = (byte << 8) & 0xfc00;
- chbase_20 = (byte << 8) & 0xfe00;
- return FALSE;
- }
-
- int ANTIC_CHACTL_PUT(mtype byte)
- {
- CHACTL = byte;
- /*
- =================================================================
- Check for vertical reflect, video invert and character blank bits
- =================================================================
- */
- switch (CHACTL & 0x07)
- {
- case 0x00 :
- char_offset = 0;
- char_delta = 1;
- invert_mask = 0x00;
- blank_mask = 0x00;
- break;
- case 0x01 :
- char_offset = 0;
- char_delta = 1;
- invert_mask = 0x00;
- blank_mask = 0x80;
- break;
- case 0x02 :
- char_offset = 0;
- char_delta = 1;
- invert_mask = 0x80;
- blank_mask = 0x00;
- break;
- case 0x03 :
- char_offset = 0;
- char_delta = 1;
- invert_mask = 0x80;
- blank_mask = 0x80;
- break;
- case 0x04 :
- char_offset = 7;
- char_delta = -1;
- invert_mask = 0x00;
- blank_mask = 0x00;
- break;
- case 0x05 :
- char_offset = 7;
- char_delta = -1;
- invert_mask = 0x00;
- blank_mask = 0x80;
- break;
- case 0x06 :
- char_offset = 7;
- char_delta = -1;
- invert_mask = 0x80;
- blank_mask = 0x00;
- break;
- case 0x07 :
- char_offset = 7;
- char_delta = -1;
- invert_mask = 0x80;
- blank_mask = 0x80;
- break;
- }
-
- return FALSE;
- }
-
- int ANTIC_DLISTL_PUT(mtype byte)
- {
- DLIST = (DLIST & 0xff00) | byte;
- DLISTINIT = DLIST;
- return FALSE;
- }
-
- int ANTIC_DLISTH_PUT(mtype byte)
- {
- DLIST = (DLIST & 0x00ff) | (byte<<8);
- DLISTINIT = DLIST;
- return FALSE;
- }
-
- int ANTIC_DMACTL_PUT(mtype byte)
- {
- /* printf("DMACTL set to %2x at %4x\n",byte,regPC); */
- DMACTL = byte;
- switch (DMACTL & 0x03)
- {
- case 0x00 :
- dmactl_xmin_noscroll = dmactl_xmax_noscroll = 0;
- dmactl_xmin_scroll = dmactl_xmax_scroll = 0;
- DMAwidth = 0;
- memory_basis = 9; /* nine cycles for refresh */
- break;
- case 0x01 :
- dmactl_xmin_noscroll = 64;
- dmactl_xmax_noscroll = ATARI_WIDTH - 64;
- dmactl_xmin_scroll = 32;
- dmactl_xmax_scroll = ATARI_WIDTH - 32;
- DMAwidth = 4;
- memory_basis = 2; /* nine cycles for refresh */
- break;
- case 0x02 :
- dmactl_xmin_noscroll = 32;
- dmactl_xmax_noscroll = ATARI_WIDTH - 32;
- dmactl_xmin_scroll = 0;
- dmactl_xmax_scroll = ATARI_WIDTH;
- memory_basis = 1;
- DMAwidth = 5;
- break;
- case 0x03 :
- dmactl_xmin_noscroll = dmactl_xmin_scroll = 0;
- dmactl_xmax_noscroll = dmactl_xmax_scroll = ATARI_WIDTH;
- memory_basis = 0;
- DMAwidth = 6;
- break;
- }
-
- pm_dma = 0; /* cycles needed for PM graphics */
-
- if (DMACTL & 0x0C) /* Player DMA enables missile DMA */
- pm_dma += 1;
- if (DMACTL & 0x08) /* Player DMA ? */
- pm_dma += 4;
-
- /* SingleLine DMACTL & 0x10 not covered here */
-
- return FALSE;
- }
-
- int ANTIC_HSCROL_PUT(mtype byte)
- {
- HSCROL = byte & 0x0f;
- return FALSE;
- }
-
- int ANTIC_NMIEN_PUT(mtype byte)
- {
- NMIEN = byte | 0x1f;
- /* printf("Wrote %d into NMIEN.\n",byte); */
- return FALSE;
- }
-
- int ANTIC_NMIRES_PUT(mtype byte)
- {
- NMIST = 0x1f;
- return FALSE;
- }
-
- int ANTIC_PMBASE_PUT(mtype byte)
- {
- UWORD pmbase_s;
- UWORD pmbase_d;
-
- PMBASE = byte;
-
- pmbase_s = (PMBASE & 0xf8) << 8;
- pmbase_d = (PMBASE & 0xfc) << 8;
-
- maddr_s = pmbase_s + 768;
- p0addr_s = pmbase_s + 1024;
- p1addr_s = pmbase_s + 1280;
- p2addr_s = pmbase_s + 1536;
- p3addr_s = pmbase_s + 1792;
-
- maddr_d = pmbase_d + 384;
- p0addr_d = pmbase_d + 512;
- p1addr_d = pmbase_d + 640;
- p2addr_d = pmbase_d + 768;
- p3addr_d = pmbase_d + 896;
-
- return FALSE;
- }
-
- int ANTIC_VSCROL_PUT(mtype byte)
- {
- VSCROL = byte & 0x0f;
- return FALSE;
- }
-
- int ANTIC_WSYNC_PUT(mtype byte)
- {
- wsync_halt ++;
- return TRUE;
- }
-
- void Init_Antic (int *argc, char *argv[],int base)
- {
- int i;
- int j;
-
- if (argc) {
- for (i=j=1;i<*argc;i++)
- {
- if (strcmp(argv[i],"-xcolpf1") == 0)
- enable_xcolpf1 = TRUE;
- else
- argv[j++] = argv[i];
- }
-
- *argc = j;
- }
-
- NMIEN = 0x1f;
- NMIST = 0x00;
- DMACTL = 0x00;
- VSCROL = 0x00;
- HSCROL = 0x00;
-
- /* setup lookup tables */
-
- memset(lookup_f,0,256*sizeof(int));
- memset(lookup_4,0,256*sizeof(int));
- memset(lookup24,0,256*sizeof(int));
- memset(lookup_9,0,256*sizeof(int));
-
- lookup_f[0x00]=PF_COLPF2;
- lookup_f[0x80]=lookup_f[0x40]=lookup_f[0x20]=
- lookup_f[0x10]=lookup_f[0x08]=lookup_f[0x04]=
- lookup_f[0x02]=lookup_f[0x01]=PF_COLPF1_FID;
-
- lookup_4[0x00]=PF2_COLBK;
- lookup_4[0x40]=lookup_4[0x10]=lookup_4[0x04]=lookup_4[0x01]=PF2_COLPF0;
- lookup_4[0x80]=lookup_4[0x20]=lookup_4[0x08]=lookup_4[0x02]=PF2_COLPF1;
- lookup_4[0xc0]=lookup_4[0x30]=lookup_4[0x0c]=lookup_4[0x03]=PF2_COLPF2;
-
- lookup24[0x00]=PF2_COLBK;
- lookup24[0x40]=lookup24[0x10]=lookup24[0x04]=lookup24[0x01]=PF2_COLPF0;
- lookup24[0x80]=lookup24[0x20]=lookup24[0x08]=lookup24[0x02]=PF2_COLPF1;
- lookup24[0xc0]=lookup24[0x30]=lookup24[0x0c]=lookup24[0x03]=PF2_COLPF3;
-
- lookup_9[0x00]=PF2_COLBK;
- lookup_9[0x80]=lookup_9[0x40]=lookup_9[0x20]=lookup_9[0x10]=
- lookup_9[0x08]=lookup_9[0x04]=lookup_9[0x02]=lookup_9[0x01]=PF2_COLPF0;
-
- memset(lookup_6+0x00,PF2_COLPF0,0x40*sizeof(int));
- memset(lookup_6+0x40,PF2_COLPF1,0x40*sizeof(int));
- memset(lookup_6+0x80,PF2_COLPF2,0x40*sizeof(int));
- memset(lookup_6+0xc0,PF2_COLPF3,0x40*sizeof(int));
-
- SetHW(base+_DMACTL,0xff0f,&ANTIC_DMACTL_GET,&ANTIC_DMACTL_PUT);
- SetHW(base+_CHACTL,0xff0f,&ANTIC_CHACTL_GET,&ANTIC_CHACTL_PUT);
- SetHW(base+_DLISTL,0xff0f,&ANTIC_DLISTL_GET,&ANTIC_DLISTL_PUT);
- SetHW(base+_DLISTH,0xff0f,&ANTIC_DLISTH_GET,&ANTIC_DLISTH_PUT);
- SetHW(base+_HSCROL,0xff0f,NULL,&ANTIC_HSCROL_PUT);
- SetHW(base+_VSCROL,0xff0f,NULL,&ANTIC_VSCROL_PUT);
- SetHW(base+_PMBASE,0xff0f,NULL,&ANTIC_PMBASE_PUT);
- SetHW(base+_CHBASE,0xff0f,&ANTIC_CHBASE_GET,&ANTIC_CHBASE_PUT);
- SetHW(base+_VCOUNT,0xff0f,&ANTIC_VCOUNT_GET,NULL);
- SetHW(base+_NMIEN,0xff0f,&ANTIC_NMIEN_GET,&ANTIC_NMIEN_PUT);
- SetHW(base+_NMIRES,0xff0f,&ANTIC_NMIST_GET,&ANTIC_NMIRES_PUT);
- SetHW(base+_WSYNC,0xff0f,&ANTIC_WSYNC_GET,&ANTIC_WSYNC_PUT);
- }
-
- void antic_blank (int nlines)
- {
- if (nlines > 0)
- {
- int nbytes;
-
- nbytes = nlines * ATARI_MODULO;
- memset (scrn_ptr, PF_COLBK, nbytes);
- }
- }
-
- static int vskipbefore = 0;
- static int vskipafter = 0;
-
- void antic_2 ()
- {
- UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
- int nchars = (xmax - xmin) >> 3;
- int i;
-
- for (i=0;i<nchars;i++)
- {
- int screendata = APeek(screenaddr);
- int chaddr;
- int invert;
- int blank;
- UBYTE *ptr = t_scrn_ptr;
- int j;
-
- screenaddr++;
- chaddr = chbase_40 + char_offset + ((screendata & 0x7f) << 3);
-
- if (screendata & invert_mask)
- invert = 0xff;
- else
- invert = 0x00;
-
- if (screendata & blank_mask)
- blank = 0x00;
- else
- blank = 0xff;
-
- for (j=0;j<8;j++)
- {
- int chdata;
-
- chdata = (APeek(chaddr) ^ invert) & blank;
- chaddr += char_delta;
-
- if (j<vskipbefore || j>vskipafter)
- continue;
-
- if (chdata) {
- *ptr++ = lookup_f[chdata & 0x80];
- *ptr++ = lookup_f[chdata & 0x40];
- *ptr++ = lookup_f[chdata & 0x20];
- *ptr++ = lookup_f[chdata & 0x10];
- *ptr++ = lookup_f[chdata & 0x08];
- *ptr++ = lookup_f[chdata & 0x04];
- *ptr++ = lookup_f[chdata & 0x02];
- *ptr++ = lookup_f[chdata & 0x01];
- } else {
- #ifdef UNALIGNED_LONG_OK
- ULONG *l_ptr = (ULONG*)ptr;
-
- *l_ptr++ = PF4_COLPF2;
- *l_ptr++ = PF4_COLPF2;
-
- ptr = (UBYTE*)l_ptr;
- #else
- UWORD *w_ptr = (UWORD*)ptr;
-
- *w_ptr++ = PF2_COLPF2;
- *w_ptr++ = PF2_COLPF2;
- *w_ptr++ = PF2_COLPF2;
- *w_ptr++ = PF2_COLPF2;
-
- ptr = (UBYTE*)w_ptr;
- #endif
- }
- ptr += (ATARI_MODULO - 8);
- }
-
- t_scrn_ptr += 8;
- }
- }
-
- /*
- * Function to display Antic Mode 3
- */
-
- void antic_3 ()
- {
- UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
- int nchars = (xmax - xmin) >> 3;
- int i;
-
- for (i=0;i<nchars;i++)
- {
- int screendata = APeek(screenaddr);
- int chaddr;
- int invert;
- int blank;
- int lowercase;
- int first=0;
- int second=0;
- UBYTE *ptr = t_scrn_ptr;
- int j;
- screenaddr++;
-
- chaddr = chbase_40 + ((screendata & 0x7f) << 3) + char_offset;
-
- if (screendata & invert_mask)
- invert = 0xff;
- else
- invert = 0x00;
-
- if (screendata & blank_mask)
- blank = 0x00;
- else
- blank = 0xff;
-
- if ((screendata & 0x60) == 0x60)
- lowercase = TRUE;
- else
- lowercase = FALSE;
-
- for (j=0;j<10;j++)
- {
- int chdata;
-
- if (lowercase) {
- switch (j) {
- case 0 :
- first = APeek(chaddr);
- chaddr += char_delta;
- chdata = 0;
- break;
- case 1 :
- second = APeek(chaddr);
- chaddr += char_delta;
- chdata = 0;
- break;
- case 8 :
- chdata = first;
- break;
- case 9 :
- chdata = second;
- break;
- default :
- chdata = APeek(chaddr);
- chaddr += char_delta;
- break;
- }
- } else if (j < 8) {
- chdata = APeek(chaddr);
- chaddr += char_delta;
- } else {
- chdata = 0;
- }
-
- chdata = (chdata ^ invert) & blank;
-
- if (j<vskipbefore || j>vskipafter)
- continue;
-
- if (chdata) {
- *ptr++ = lookup_f[chdata & 0x80];
- *ptr++ = lookup_f[chdata & 0x40];
- *ptr++ = lookup_f[chdata & 0x20];
- *ptr++ = lookup_f[chdata & 0x10];
- *ptr++ = lookup_f[chdata & 0x08];
- *ptr++ = lookup_f[chdata & 0x04];
- *ptr++ = lookup_f[chdata & 0x02];
- *ptr++ = lookup_f[chdata & 0x01];
- } else {
- *ptr++ = PF_COLPF2;
- *ptr++ = PF_COLPF2;
- *ptr++ = PF_COLPF2;
- *ptr++ = PF_COLPF2;
- *ptr++ = PF_COLPF2;
- *ptr++ = PF_COLPF2;
- *ptr++ = PF_COLPF2;
- *ptr++ = PF_COLPF2;
- }
-
- ptr += (ATARI_MODULO - 8);
- }
-
- t_scrn_ptr += 8;
- }
- }
-
- /*
- * Funtion to display Antic Mode 4
- */
-
- void antic_4 ()
- {
- UWORD *t_scrn_ptr = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
- int nchars = (xmax - xmin) >> 3;
- int i;
-
- for (i=0;i<nchars;i++)
- {
- int screendata = APeek(screenaddr);
- int chaddr;
- int *lookup;
- UWORD *ptr = t_scrn_ptr;
- int j;
-
- screenaddr++;
- chaddr = chbase_40 + ((screendata & 0x7f) << 3) + char_offset;
-
- if (screendata & 0x80)
- lookup = lookup24;
- else
- lookup = lookup_4;
-
- for (j=0;j<8;j++)
- {
- int chdata;
-
- chdata = APeek(chaddr);
- chaddr += char_delta;
-
- if (j<vskipbefore || j>vskipafter)
- continue;
-
- if (chdata) {
- *ptr++ = lookup[chdata & 0xc0];
- *ptr++ = lookup[chdata & 0x30];
- *ptr++ = lookup[chdata & 0x0c];
- *ptr++ = lookup[chdata & 0x03];
- } else {
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- }
-
- ptr += ((ATARI_MODULO - 8) >> 1);
-
- }
-
- t_scrn_ptr += 4;
- }
- }
-
- /*
- * Function to Display Antic Mode 5
- */
-
- void antic_5 ()
- {
- UWORD *t_scrn_ptr1 = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
- int nchars = nchars = (xmax - xmin) >> 3;
- int i;
-
- for (i=0;i<nchars;i++)
- {
- int screendata = APeek(screenaddr);
- int chaddr;
- int *lookup;
- UWORD *ptr1 = t_scrn_ptr1;
- int j;
-
- screenaddr++;
- chaddr = chbase_40 + ((UWORD)(screendata & 0x7f) << 3) + char_offset;
-
- if (screendata & 0x80)
- lookup = lookup24;
- else
- lookup = lookup_4;
-
- for (j=0;j<16;j++)
- {
- int chdata;
-
- chdata = APeek(chaddr);
- if (j & 0x01) chaddr += char_delta;
-
- if (j<vskipbefore || j>vskipafter)
- continue;
-
- if (chdata) {
- *ptr1++ = lookup[chdata & 0xc0];
- *ptr1++ = lookup[chdata & 0x30];
- *ptr1++ = lookup[chdata & 0x0c];
- *ptr1++ = lookup[chdata & 0x03];
- } else {
- *ptr1++ = PF2_COLBK;
- *ptr1++ = PF2_COLBK;
- *ptr1++ = PF2_COLBK;
- *ptr1++ = PF2_COLBK;
- }
-
- ptr1 += ((ATARI_MODULO - 8) >> 1);
- }
-
- t_scrn_ptr1 += (8 >> 1);
- }
- }
-
- /*
- * Function to Display Antic Mode 6
- */
-
- void antic_6 ()
- {
- UWORD *t_scrn_ptr = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
- int nchars = (xmax - xmin) >> 4; /* Divide by 16 */
- int i;
-
- for (i=0;i<nchars;i++)
- {
- int screendata = APeek(screenaddr);
- int chaddr;
- UWORD *ptr = t_scrn_ptr;
- int colour=0;
- int j;
-
- screenaddr++;
- chaddr = chbase_20 + ((UWORD)(screendata & 0x3f) << 3) + char_offset;
- colour = lookup_6[screendata];
-
- for (j=0;j<8;j++) {
- int chdata;
- int k;
-
- chdata = memory[chaddr];
- chaddr += char_delta;
-
- if (j<vskipbefore || j>vskipafter)
- continue;
-
- for (k=0;k<8;k++)
- {
- if (chdata & 0x80)
- *ptr++ = colour;
- else *ptr++ = PF2_COLBK;
-
- chdata = chdata << 1;
- }
-
- ptr += ((ATARI_MODULO - 16) >> 1);
- }
-
- t_scrn_ptr += (16 >> 1);
- }
- }
-
- /*
- * Function to Display Antic Mode 7
- */
-
- void antic_7 ()
- {
- UWORD *t_scrn_ptr1 = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
- int nchars = (xmax - xmin) >> 4; /* Divide by 16 */
- int i;
-
- for (i=0;i<nchars;i++)
- {
- int screendata = APeek(screenaddr);
- int chaddr;
- UWORD *ptr1 = t_scrn_ptr1;
- int colour=0;
- int j;
-
- screenaddr++;
- chaddr = chbase_20 + ((UWORD)(screendata & 0x3f) << 3) + char_offset;
- colour = lookup_6[screendata];
-
- for (j=0;j<16;j++)
- {
- int chdata;
- int k;
-
- chdata = APeek(chaddr);
-
- if (j & 0x01) chaddr += char_delta;
-
- if (j<vskipbefore || j>vskipafter)
- continue;
-
- for (k=0;k<8;k++)
- {
- if (chdata & 0x80) *ptr1++ = colour;
- else *ptr1++ = PF2_COLBK;
- chdata = chdata << 1;
- }
-
- ptr1 += ((ATARI_MODULO - 16) >> 1);
- }
-
- t_scrn_ptr1 += (16 >> 1);
- }
- }
-
- /*
- * Function to Display Antic Mode 8
- */
-
- void antic_8 ()
- {
- UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
- int nbytes = (xmax - xmin) >> 5; /* Divide by 32 */
- int i;
-
- for (i=0;i<nbytes;i++)
- {
- int screendata = APeek(screenaddr);
- int j;
-
- screenaddr++;
-
- for (j=0;j<4;j++) {
- int colour;
- UBYTE *ptr = t_scrn_ptr;
- int k;
-
- colour = lookup_4[screendata & 0xc0];
-
- for (k=0;k<8;k++) {
- if (k<vskipbefore || k>vskipafter)
- continue;
- memset (ptr, colour, 8);
- ptr += ATARI_MODULO;
- }
-
- screendata = screendata << 2;
- t_scrn_ptr += 8;
- }
- }
- }
-
- /*
- * Function to Display Antic Mode 9
- */
-
- void antic_9 ()
- {
- UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
- int nbytes = (xmax - xmin) >> 5; /* Divide by 32 */
- int i;
-
- for (i=0;i<nbytes;i++)
- {
- int screendata = APeek(screenaddr);
- int j;
-
- screenaddr++;
- for (j=0;j<8;j++) {
- int colour;
- UBYTE *ptr = t_scrn_ptr;
- int k;
-
- colour = lookup_9[screendata & 0x80];
-
- for (k=0;k<4;k++) {
- if (k<vskipbefore || k>vskipafter)
- continue;
- memset (ptr, colour, 4);
- ptr += ATARI_MODULO;
- }
-
- screendata = screendata << 1;
- t_scrn_ptr += 4;
- }
- }
- }
-
- /*
- * Function to Display Antic Mode a
- */
-
- void antic_a ()
- {
- UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
- int nbytes = (xmax - xmin) >> 4; /* Divide by 16 */
- int i;
-
- for (i=0;i<nbytes;i++)
- {
- int screendata = APeek(screenaddr);
- int j;
-
- screenaddr++;
-
- for (j=0;j<4;j++)
- {
- int colour;
- UBYTE *ptr = t_scrn_ptr;
- int k;
-
- colour = lookup_4[screendata & 0xc0];
-
- for (k=0;k<4;k++) {
- if (k<vskipbefore || k>vskipafter)
- continue;
- memset (ptr, colour, 4);
- ptr += ATARI_MODULO;
- }
-
- screendata = screendata << 2;
- t_scrn_ptr += 4;
- }
- }
- }
-
- /*
- * Function to Display Antic Mode b
- */
-
- void antic_b ()
- {
- UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
- int nbytes = (xmax - xmin) >> 4; /* Divide by 16 */
- int i;
-
- for (i=0;i<nbytes;i++)
- {
- int screendata = APeek(screenaddr);
- int j;
- screenaddr++;
-
- for (j=0;j<8;j++) {
- int colour;
- UBYTE *ptr = t_scrn_ptr;
- int k;
-
- colour = lookup_9[screendata & 0x80];
-
- for (k=0;k<2;k++) {
- if (k<vskipbefore || k>vskipafter)
- continue;
- *ptr++ = colour;
- *ptr++ = colour;
- ptr += (ATARI_MODULO-2);
- }
-
- screendata = screendata << 1;
- t_scrn_ptr += 2;
- }
- }
- }
-
-
-
-
- /*
- * Function to Display Antic Mode c
- */
-
- void antic_c ()
- {
- UWORD *t_scrn_ptr1 = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
- int nbytes = (xmax - xmin) >> 4;
- int i;
-
- for (i=0;i<nbytes;i++)
- {
- UWORD *ptr=t_scrn_ptr1;
- int j;
- int screendata=APeek(screenaddr);
-
- screenaddr++;
-
- for (j=0;j<2;j++) {
-
- if (j<vskipbefore || j>vskipafter)
- continue;
-
- if (screendata) {
- *ptr++ = lookup_9[screendata & 0x80];
- *ptr++ = lookup_9[screendata & 0x40];
- *ptr++ = lookup_9[screendata & 0x20];
- *ptr++ = lookup_9[screendata & 0x10];
- *ptr++ = lookup_9[screendata & 0x08];
- *ptr++ = lookup_9[screendata & 0x04];
- *ptr++ = lookup_9[screendata & 0x02];
- *ptr++ = lookup_9[screendata & 0x01];
- } else {
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- }
- ptr += ((ATARI_MODULO-8)>>1);
- }
- t_scrn_ptr1 += 8;
- }
- }
-
- /*
- * Function to Display Antic Mode d
- */
-
- void antic_d ()
- {
- UWORD *t_scrn_ptr1 = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
- int nbytes = (xmax - xmin) >> 3;
- int i;
-
- for (i=0;i<nbytes;i++)
- {
- UWORD *ptr=t_scrn_ptr1;
- int j;
- int screendata=APeek(screenaddr);
-
- screenaddr++;
-
- for (j=0;j<2;j++) {
-
- if (j<vskipbefore || j>vskipafter)
- continue;
-
- if (screendata) {
- *ptr++ = lookup_4[screendata & 0xc0];
- *ptr++ = lookup_4[screendata & 0x30];
- *ptr++ = lookup_4[screendata & 0x0c];
- *ptr++ = lookup_4[screendata & 0x03];
- } else {
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- *ptr++ = PF2_COLBK;
- }
- ptr += ((ATARI_MODULO-8)>>1);
- }
- t_scrn_ptr1 += 4;
- }
- }
-
- /*
- * Function to display Antic Mode e
- */
-
- void antic_e ()
- {
- UWORD *t_scrn_ptr = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
- int nbytes = (xmax - xmin) >> 3;
- int i;
-
- for (i=0;i<nbytes;i++)
- {
- int screendata = APeek(screenaddr);
- screenaddr++;
-
- if (screendata)
- {
- *t_scrn_ptr++ = lookup_4[screendata & 0xc0];
- *t_scrn_ptr++ = lookup_4[screendata & 0x30];
- *t_scrn_ptr++ = lookup_4[screendata & 0x0c];
- *t_scrn_ptr++ = lookup_4[screendata & 0x03];
- }
- else
- {
- #ifdef UNALIGNED_LONG_OK
- ULONG *l_ptr = (ULONG*)t_scrn_ptr;
-
- *l_ptr++ = PF4_COLBK;
- *l_ptr++ = PF4_COLBK;
-
- t_scrn_ptr = (UWORD*)l_ptr;
- #else
- *t_scrn_ptr++ = PF2_COLBK;
- *t_scrn_ptr++ = PF2_COLBK;
- *t_scrn_ptr++ = PF2_COLBK;
- *t_scrn_ptr++ = PF2_COLBK;
- #endif
- }
- }
- }
-
- /*
- * Function to display Antic Mode f
- */
-
- void antic_f ()
- {
- UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
- int nbytes = (xmax - xmin) >> 3;
- int i;
-
- for (i=0;i<nbytes;i++)
- {
- UBYTE screendata = APeek(screenaddr);
- screenaddr++;
-
- if (screendata)
- {
- *t_scrn_ptr++ = lookup_f[screendata & 0x80];
- *t_scrn_ptr++ = lookup_f[screendata & 0x40];
- *t_scrn_ptr++ = lookup_f[screendata & 0x20];
- *t_scrn_ptr++ = lookup_f[screendata & 0x10];
- *t_scrn_ptr++ = lookup_f[screendata & 0x08];
- *t_scrn_ptr++ = lookup_f[screendata & 0x04];
- *t_scrn_ptr++ = lookup_f[screendata & 0x02];
- *t_scrn_ptr++ = lookup_f[screendata & 0x01];
- }
- else
- {
- *t_scrn_ptr++ = PF_COLPF2;
- *t_scrn_ptr++ = PF_COLPF2;
- *t_scrn_ptr++ = PF_COLPF2;
- *t_scrn_ptr++ = PF_COLPF2;
- *t_scrn_ptr++ = PF_COLPF2;
- *t_scrn_ptr++ = PF_COLPF2;
- *t_scrn_ptr++ = PF_COLPF2;
- *t_scrn_ptr++ = PF_COLPF2;
- }
- }
- }
-
- /*
- *****************************************************************
- * *
- * Section : Display List *
- * Original Author : David Firth *
- * Date Written : 28th May 1995 *
- * Version : 1.0 *
- * *
- * Description *
- * ----------- *
- * *
- * Section that handles Antic Display List. Not required for *
- * BASIC version. *
- * *
- *****************************************************************
- */
-
- void pmg_dma (void)
- {
- int yhalf = ypos >> 1;
- /* single line shift not yet implemented.... */
-
- if (DMACTL & 0x08)
- {
- if (DMACTL & 0x10)
- {
- GRAFP0 = memory[p0addr_s + ypos];
- GRAFP1 = memory[p1addr_s + ypos];
- GRAFP2 = memory[p2addr_s + ypos];
- GRAFP3 = memory[p3addr_s + ypos];
- }
- else
- {
- GRAFP0 = memory[p0addr_d + yhalf - delayp0];
- GRAFP1 = memory[p1addr_d + yhalf - delayp1];
- GRAFP2 = memory[p2addr_d + yhalf - delayp2];
- GRAFP3 = memory[p3addr_d + yhalf - delayp3];
- }
- }
-
- if (DMACTL & 0x0C) /* Player DMA enables missile DMA as well */
- {
- if (DMACTL & 0x10)
- GRAFM = memory[maddr_s + ypos];
- else {
- int mis0,mis1,mis2,mis3;
-
- mis0 = memory[maddr_d + yhalf - delaym0];
- mis1 = memory[maddr_d + yhalf - delaym1];
- mis2 = memory[maddr_d + yhalf - delaym2];
- mis3 = memory[maddr_d + yhalf - delaym3];
-
- GRAFM = (mis0 & 0x03) | (mis1 & 0x0c) | (mis2 & 0x30) | (mis3 & 0xc0);
- }
- }
- }
-
- static void Clear_Border(int hscrol)
- {
- int scrol=HSCROL+HSCROL;
- int shift=FILLIN_OFFSET;
- int left=FILLIN_OFFSET+dmactl_xmin_noscroll;
-
- if (hscrol) {
- shift -= scrol;
- if ((DMACTL & 0x03)!=0x03)
- left -= scrol;
- }
-
- memset(scrn_ptr,PF_COLBK,left);
- memset(scrn_ptr+dmactl_xmax_noscroll+shift,PF_COLBK,
- ATARI_MODULO-dmactl_xmax_noscroll-shift);
- }
-
- static void ANTIC_Scanline(int dmacycles,int nmi,int hscrol)
- {
- int before;
- int after;
- int add;
-
- before=cc_middle-before_dma-dmacycles;
- after=114-cc_middle-after_wsync;
- if (before<0) {
- after += before;
- before = 0;
- }
- add = carry;
- Clear_Border(hscrol);
- if (!wsync_halt) {
- if (before_dma>0)
- add = GO(before_dma+add);
- if (nmi) {
- before += add;
- before -= dli_delay;
- if (before>0) {
- NMI();
- nmi = FALSE;
- add = GO(before);
- }
- } else {
- before += add;
- if (before>0)
- add = GO(before);
- }
- }
- pmg_dma ();
- Atari_ScanLine (hscrol);
- if (!wsync_halt) {
- if (nmi) {
- after += add;
- after -= dli_delay;
- if (after>0) {
- NMI();
- nmi = FALSE;
- add = GO(after);
- }
- } else {
- after += add;
- if (after>0)
- add = GO(after);
- }
- }
- wsync_halt=0;
- if (nmi) {
- NMI();
- add = GO(after_wsync-dli_delay+add);
- } else add = GO(after_wsync+add);
- carry = add;
-
- scrn_ptr += ATARI_MODULO;
- ypos++;
-
- }
-
- void ANTIC_RunDisplayList (void)
- {
- int JVB=FALSE;
- int vscrol_flag=0;
- int nlines=0;
- int i;
- int IR;
- int acnt;
- int acntn;
- int dmawidth;
- int hscrol;
-
- wsync_halt = 0;
-
- /*
- * VCOUNT must equal zero for some games but the first line starts
- * when VCOUNT=4. This portion processes when VCOUNT=0, 1, 2 and 3
- */
-
- scrn_ptr = (UBYTE*)atari_screen;
-
- DLIST=DLISTINIT;
- for (ypos = 0; ypos <8 ;ypos++) {
- carry=GO (carry+105); /* 114 minus 9 memory cycles */
- }
-
- NMIST = 0x00;
-
- for (ypos = 8, JVB=FALSE ; ypos < (ATARI_HEIGHT + 8);) {
-
- if ((DMACTL & 0x10) || (ypos & 0x01)==0)
- acntn=pm_dma;
- else
- acntn=0;
- acnt = 0;
- /* Counter for DMA type needed by ANTIC. One cycle per byte
- acnt is the counter for the extra cycles of the first scanline
- of the modeline acntn for all following lines */
-
- if (JVB || (DMACTL & 0x20)==0) {
- antic_blank(1);
- ANTIC_Scanline(9,FALSE,FALSE);
- } else {
- IR = APeek(DLIST);
- DLIST++;
- acnt++;
-
- vskipbefore = 0;
- vskipafter = 127;
- hscrol = FALSE;
- xmin = dmactl_xmin_noscroll;
- xmax = dmactl_xmax_noscroll;
- dmawidth = DMAwidth;
-
- switch (IR & 0x0f)
- {
- case 0x00 :
- nlines = ((IR >> 4) & 0x07) + 1;
- antic_blank (nlines);
- break;
- case 0x01 :
- if (IR & 0x40)
- JVB = TRUE;
- DLIST = DAPeek(DLIST);
- acnt += 2;
- nlines = 1;
- antic_blank (1); /* Jump aparently uses 1 scan line */
- break;
- default :
- if (IR & 0x40) {
- screenaddr = DAPeek(DLIST);
- DLIST += 2;
- acnt += 2;
- }
-
- if (IR & 0x20) {
- if (!vscrol_flag) {
- vskipbefore = (int)VSCROL;
- vscrol_flag = TRUE;
- }
- }
- else if (vscrol_flag) {
- vskipafter = VSCROL;
- vscrol_flag = FALSE;
- }
-
- if (IR & 0x10) {
- xmin = dmactl_xmin_scroll;
- xmax = dmactl_xmax_scroll;
- hscrol = TRUE;
- if (dmawidth<6) {
- dmawidth++;
- acntn--; /* one memory refresh cycle is dropped */
- }
- }
-
- switch (IR & 0x0f) {
- case 0x02 :
- nlines = 8;
- acnt += dmawidth*8+memory_basis-9;
- acntn += dmawidth*8+9;
- antic_2 ();
- break;
- case 0x03 :
- nlines = 10;
- acnt += dmawidth*8+memory_basis-9;
- acntn += dmawidth*8+9;
- antic_3 ();
- break;
- case 0x04 :
- nlines = 8;
- acnt += dmawidth*8+memory_basis-9;
- acntn += dmawidth*8+9;
- antic_4 ();
- break;
- case 0x05 :
- nlines = 16;
- acnt += dmawidth*8+memory_basis-9;
- acntn += dmawidth*8+9;
- antic_5 ();
- break;
- case 0x06 :
- nlines = 8;
- acnt += dmawidth*4;
- acntn += dmawidth*4+9;
- antic_6 ();
- break;
- case 0x07 :
- nlines = 16;
- acnt += dmawidth*4;
- acntn += dmawidth*4+9;
- antic_7 ();
- break;
- case 0x08 :
- nlines = 8;
- acnt += dmawidth*2+9;
- antic_8 ();
- break;
- case 0x09 :
- nlines = 4;
- acnt += dmawidth*2+9;
- antic_9 ();
- break;
- case 0x0a :
- nlines = 4;
- acnt += dmawidth*4+9;
- antic_a ();
- break;
- case 0x0b :
- nlines = 2;
- acnt += dmawidth*4+9;
- antic_b ();
- break;
- case 0x0c :
- nlines = 1;
- acnt += dmawidth*4+9;
- antic_c ();
- break;
- case 0x0d :
- nlines = 2;
- acnt += dmawidth*8+9;
- antic_d ();
- break;
- case 0x0e :
- nlines = 1;
- acnt += dmawidth*8+9;
- antic_e ();
- break;
- case 0x0f :
- nlines = 1;
- acnt += dmawidth*8+9;
- antic_f ();
- break;
- default :
- printf("IR %x caused problems.\n",IR);
- nlines = 0;
- break;
- }
- break;
- }
-
- if (nlines > 0) {
- int dma;
- int nmi=FALSE;
-
- nlines--;
- dma=acnt+acntn;
- if (vskipafter<nlines)
- nlines=vskipafter;
- for (i=vskipbefore;i<nlines;i++) {
- ANTIC_Scanline(dma,FALSE,hscrol);
- dma=acntn;
- }
-
- if (IR & 0x80) {
- if (NMIEN & 0x80) {
- NMIST = 0x80;
- nmi = TRUE;
- }
- }
-
- ANTIC_Scanline(dma,nmi,hscrol);
- }
- }
- }
-
- for(ypos=248; ypos<vsync_pos;ypos++)
- carry = GO(carry+105);
-
- NMIST = 0x40; /* Set VBLANK */
- if (NMIEN & 0x40) {
- carry=GO (carry+7);
- /* Needed for programs that monitor NMIST (Spy's Demise, GORF) */
- NMI ();
- carry -= dli_delay+7; /* Needed by 6502 to react */
- }
-
- if (tv_mode == PAL)
- for (ypos=vsync_pos;ypos<312;ypos++)
- carry=GO (carry+105);
- else
- for (ypos=vsync_pos;ypos<262;ypos++)
- carry=GO (carry+105);
- }
-
-